

package com.maoshi.shop.distribution.comment.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.maoshi.shop.bean.enums.OfflineHandleEventStatus;
import com.maoshi.shop.bean.enums.OfflineHandleEventType;
import com.maoshi.shop.bean.model.OfflineHandleEvent;
import com.maoshi.shop.bean.param.OfflineHandleEventAuditParam;
import com.maoshi.shop.common.exception.MaoshiShopBindException;
import com.maoshi.shop.common.util.Arith;
import com.maoshi.shop.common.util.Json;
import com.maoshi.shop.distribution.comment.Enums.DistributionProdStateEnum;
import com.maoshi.shop.distribution.comment.dao.DistributionProdMapper;
import com.maoshi.shop.distribution.comment.dao.DistributionUserMapper;
import com.maoshi.shop.distribution.comment.dto.DistributionProdDto;
import com.maoshi.shop.distribution.comment.model.DistributionLevel;
import com.maoshi.shop.distribution.comment.model.DistributionLevelSet;
import com.maoshi.shop.distribution.comment.model.DistributionProd;
import com.maoshi.shop.distribution.comment.model.DistributionUser;
import com.maoshi.shop.distribution.comment.po.DistributionProdPO;
import com.maoshi.shop.distribution.comment.service.DistributionLevelService;
import com.maoshi.shop.distribution.comment.service.DistributionLevelSetService;
import com.maoshi.shop.distribution.comment.service.DistributionProdService;
import com.maoshi.shop.distribution.comment.vo.DistributionAwardDataVO;
import com.maoshi.shop.service.OfflineHandleEventService;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author lgh on 2019/04/01.
 */
@Service
@AllArgsConstructor
public class DistributionProdServiceImpl extends ServiceImpl<DistributionProdMapper, DistributionProd> implements DistributionProdService {

    private final DistributionProdMapper distributionProdMapper;

    private final DistributionLevelService distributionLevelService;

    private final DistributionLevelSetService distributionLevelSetService;

    private final DistributionUserMapper distributionUserMapper;

    private final OfflineHandleEventService offlineHandleEventService;

    @Override
    public IPage<DistributionProd> distributionProdsPage(Page page, DistributionProd distributionProd, String prodName) {
        return distributionProdMapper.distributionProdsPage(page, distributionProd, prodName);
    }

    @Override
    public List<DistributionProdDto> distributionProdDtoPage(Page<DistributionProdDto> page, String prodName, Integer sort, Integer orderBy, DistributionUser distributionUser) {
        Long shopId = distributionUser.getShopId();

        DistributionLevelSet distributionLevelSet = distributionLevelSetService.getByShopId();
        DistributionLevel levelInfo = distributionLevelService.getLevelInfo(distributionUser.getLevel(), distributionLevelSet.getDistributionLevels());

        // 商品默认
        DistributionAwardDataVO defaultAwardData = getDefaultAwardData(distributionLevelSet, levelInfo);


        IPage<DistributionProdPO> distributionProdPOPage = distributionProdMapper.distributionProdPOPage(page, prodName, sort, orderBy);

        // 获取商品的分佣金额，或分佣奖励
        List<DistributionProdDto> distributionProdDtoList = new ArrayList<>();
        for (DistributionProdPO distributionProdPO : distributionProdPOPage.getRecords()) {
            //po转dto
            DistributionProdDto distributionProdDto = new DistributionProdDto();
            distributionProdDto.setProdId(distributionProdPO.getProdId());
            distributionProdDto.setProdName(distributionProdPO.getProdName());
            distributionProdDto.setPic(distributionProdPO.getPic());
            distributionProdDto.setPrice(distributionProdPO.getPrice());
            //获取计算好的奖励
            DistributionAwardDataVO distributionAwardDataVO = getAwardDataVO(distributionProdPO, defaultAwardData, levelInfo.getLevel());

            distributionProdDto.setAwardProportion(distributionAwardDataVO.getAwardProportion());
            distributionProdDto.setAwardNumber(distributionAwardDataVO.getAwardNumber());
            distributionProdDto.setParentAwardNumber(distributionAwardDataVO.getParentAwardNumber());
            //添加到集合中
            distributionProdDtoList.add(distributionProdDto);
        }


        return distributionProdDtoList;
    }

    /**
     * 根据分销商品设置、分享人id，计算奖励数据
     *
     * @param distributionProdPO
     * @param distributionUserId
     * @return
     */
    @Override
    public DistributionAwardDataVO getAwardDataVO(DistributionProdPO distributionProdPO, Long distributionUserId) {
        DistributionAwardDataVO distributionAwardDataVO = new DistributionAwardDataVO();
        distributionAwardDataVO.setAwardNumber(0.0);
        distributionAwardDataVO.setParentAwardNumber(0.0);

        //查看推广员信息
        DistributionUser distributionUser = distributionUserMapper.selectById(distributionUserId);

        //根据店铺id获取等级设置
        DistributionLevelSet distributionLevelSet = distributionLevelSetService.getByShopId();
        DistributionLevel levelInfo = distributionLevelService.getLevelInfo(distributionUser.getLevel(), distributionLevelSet.getDistributionLevels());
        //获取默认设置收益
        distributionAwardDataVO = getDefaultAwardData(distributionLevelSet, levelInfo);

        //如果为分销商品自定义奖励
        distributionAwardDataVO = getAwardDataVO(distributionProdPO, distributionAwardDataVO, distributionUser.getLevel());

        //如果计算为按比例计算，则转化为具体金额
        if (Objects.isNull(distributionAwardDataVO.getAwardProportion()) || Objects.equals(distributionAwardDataVO.getAwardProportion(), 0)) {
            distributionAwardDataVO.setAwardProportion(0);
            //根据商品价格,计算得到的佣金
//            distributionAwardDataVO.setAwardNumber(Arith.mul(distributionProdPO.getPrice(), Arith.div(distributionAwardDataVO.getAwardNumber(), 100)));
            distributionAwardDataVO.setAwardNumber(Arith.div(Arith.mul(distributionProdPO.getPrice(),distributionAwardDataVO.getAwardNumber()),100));
            //查看是否开启邀请人奖励
            if (distributionProdPO.getParentAwardSet() == 1) {
//                distributionAwardDataVO.setParentAwardNumber(Arith.mul(distributionProdPO.getPrice(), Arith.div(distributionAwardDataVO.getParentAwardNumber(), 100)));
                distributionAwardDataVO.setParentAwardNumber(Arith.div(Arith.mul(distributionProdPO.getPrice(),distributionAwardDataVO.getParentAwardNumber()),100));
            }
        }
        return distributionAwardDataVO;

    }


    /**
     * 获取商品默认奖励设置
     *
     * @param distributionLevelSet
     * @param levelInfo
     * @return
     */
    private DistributionAwardDataVO getDefaultAwardData(DistributionLevelSet distributionLevelSet, DistributionLevel levelInfo) {

        DistributionAwardDataVO distributionAwardDataVO = new DistributionAwardDataVO();

        distributionAwardDataVO.setAwardNumber(levelInfo.getAwardNumber());
        distributionAwardDataVO.setParentAwardNumber(levelInfo.getParentAwardNumber());
        // 奖励比例或数额
        distributionAwardDataVO.setAwardProportion(distributionLevelSet.getAwardProportion());
        //是否开启默认奖励
        if (distributionLevelSet.getAwardSwitch() == 0) {
            //没开启默认奖励,将奖励数额归零
            distributionAwardDataVO.setAwardNumber(0.0);
        }
        //是否开启了默认上级奖励
        if (distributionLevelSet.getParentAwardSwitch() == 0) {
            //如果没开启,就将奖励数额归零
            distributionAwardDataVO.setParentAwardNumber(0.0);
        }
        return distributionAwardDataVO;
    }

    /**
     * 根据分销商品对象和分销员等级计算出 奖励数据
     *
     * @param distributionProdPO
     * @return
     */
    private DistributionAwardDataVO getAwardDataVO(DistributionProdPO distributionProdPO, DistributionAwardDataVO defaultDistributionAwardData, int level) {
        //判断商品奖励 是否为默认奖励
        if (distributionProdPO.getDefaultReward() == 1) {
            return defaultDistributionAwardData;
        }

        DistributionAwardDataVO distributionAwardDataVO = new DistributionAwardDataVO();

        //奖励比例或数额
        distributionAwardDataVO.setAwardProportion(distributionProdPO.getAwardProportion());

        // 不按照等级进行设置
        if (distributionProdPO.getAwardNumberSet() == 0) {
            distributionAwardDataVO.setAwardNumber(Double.valueOf(distributionProdPO.getAwardNumbers()));
            distributionAwardDataVO.setParentAwardNumber(Double.valueOf(distributionProdPO.getParentAwardNumbers()));
            return distributionAwardDataVO;
        }
        List<Double> awardNumbers = Json.parseArray(distributionProdPO.getAwardNumbers(), Double[].class);
        distributionAwardDataVO.setAwardNumber(awardNumbers.get(level - 1));

        List<Double> parentAwardNumbers = Json.parseArray(distributionProdPO.getParentAwardNumbers(), Double[].class);
        distributionAwardDataVO.setParentAwardNumber(parentAwardNumbers.get(level - 1));

        return distributionAwardDataVO;
    }

    @Override
    @Cacheable(cacheNames = "DistributionProdPO", key = "#prodId")
    public DistributionProdPO getDistributionProdPOByProdId(Long prodId) {
        return distributionProdMapper.getDistributionProdPOByProdId(prodId);
    }

    @Override
    @CacheEvict(cacheNames = "DistributionProdPO", key = "#prodId")
    public void removeDistributionProdPOCacheByProdId(Long prodId) {

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void offline(DistributionProd distributionProd, String offlineReason, Long sysUserId) {
        // 添加下线处理记录
        Date now = new Date();
        OfflineHandleEvent offlineHandleEvent = new OfflineHandleEvent();
        offlineHandleEvent.setShopId(distributionProd.getShopId());
        offlineHandleEvent.setHandleId(distributionProd.getDistributionProdId());
        offlineHandleEvent.setHandleType(OfflineHandleEventType.DISTRIBUTION_PROD.getValue());
        offlineHandleEvent.setCreateTime(now);
        offlineHandleEvent.setOfflineReason(offlineReason);
        offlineHandleEvent.setHandlerId(sysUserId);
        offlineHandleEvent.setStatus(OfflineHandleEventStatus.OFFLINE_BY_PLATFORM.getValue());
        offlineHandleEvent.setUpdateTime(now);
        offlineHandleEventService.save(offlineHandleEvent);

        // 更新活动状态为下线
        if (distributionProdMapper.updateState(distributionProd.getDistributionProdId(), DistributionProdStateEnum.OFFLINE.getValue()) < 0) {
            throw new MaoshiShopBindException("更新活动商品失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditDistributionProd(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId) {
        // 审核通过
        if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.AGREE_BY_PLATFORM.getValue())) {
            // 更新活动状态
            distributionProdMapper.updateState(offlineHandleEventAuditParam.getHandleId(), DistributionProdStateEnum.PUT_OFF.getValue());
        }
        // 审核不通过
        else if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.DISAGREE_BY_PLATFORM.getValue())) {
            distributionProdMapper.updateState(offlineHandleEventAuditParam.getHandleId(), DistributionProdStateEnum.OFFLINE.getValue());
        }
        offlineHandleEventService.auditOfflineEvent(offlineHandleEventAuditParam, sysUserId);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditApply(Long eventId, Long distributionProdId, String reapplyReason) {
        // 更新活动为待审核状态
        distributionProdMapper.updateState(distributionProdId, DistributionProdStateEnum.WAIT_AUDIT.getValue());

        // 更新事件状态
        offlineHandleEventService.updateToApply(eventId, reapplyReason);
    }

}
